"""
AI Agent Pro - 日志配置模块
"""

import json
import logging
import logging.config
import sys
from datetime import datetime
from pathlib import Path
from typing import Any, Dict

import structlog
from pythonjsonlogger import jsonlogger

from app.core.config import get_settings

settings = get_settings()


def setup_logging():
    """设置应用日志配置"""
    
    # 创建日志目录
    log_dir = Path("logs")
    log_dir.mkdir(exist_ok=True)
    
    # 自定义日志格式化器
    class CustomJSONFormatter(jsonlogger.JsonFormatter):
        def add_fields(self, log_record, record, message_dict):
            super(CustomJSONFormatter, self).add_fields(log_record, record, message_dict)
            
            # 添加时间戳
            log_record['timestamp'] = datetime.utcnow().isoformat()
            
            # 添加应用信息
            log_record['app'] = settings.app_name
            log_record['version'] = settings.app_version
            log_record['environment'] = settings.environment
            
            # 添加日志级别
            log_record['level'] = record.levelname
            
            # 添加日志来源
            log_record['logger'] = record.name
            log_record['module'] = record.module
            log_record['function'] = record.funcName
            log_record['line'] = record.lineno
    
    # 控制台格式化器
    class ColoredFormatter(logging.Formatter):
        """彩色控制台格式化器"""
        
        # 颜色代码
        COLORS = {
            'DEBUG': '\033[36m',    # 青色
            'INFO': '\033[32m',     # 绿色
            'WARNING': '\033[33m',  # 黄色
            'ERROR': '\033[31m',    # 红色
            'CRITICAL': '\033[35m', # 紫色
        }
        RESET = '\033[0m'
        
        def format(self, record):
            # 添加颜色
            if record.levelname in self.COLORS:
                record.levelname = f"{self.COLORS[record.levelname]}{record.levelname}{self.RESET}"
            
            return super().format(record)
    
    # 日志配置
    logging_config = {
        'version': 1,
        'disable_existing_loggers': False,
        'formatters': {
            'json': {
                '()': CustomJSONFormatter,
                'format': '%(asctime)s %(name)s %(levelname)s %(message)s'
            },
            'console': {
                '()': ColoredFormatter,
                'format': '%(asctime)s | %(levelname)-8s | %(name)-20s | %(message)s',
                'datefmt': '%Y-%m-%d %H:%M:%S'
            },
            'file': {
                'format': '%(asctime)s | %(levelname)-8s | %(name)-20s | %(module)s:%(lineno)d | %(message)s',
                'datefmt': '%Y-%m-%d %H:%M:%S'
            }
        },
        'handlers': {
            'console': {
                'class': 'logging.StreamHandler',
                'level': settings.log_level,
                'formatter': 'console',
                'stream': sys.stdout
            },
            'file_info': {
                'class': 'logging.handlers.RotatingFileHandler',
                'level': 'INFO',
                'formatter': 'file',
                'filename': 'logs/app.log',
                'maxBytes': 10485760,  # 10MB
                'backupCount': 5,
                'encoding': 'utf8'
            },
            'file_error': {
                'class': 'logging.handlers.RotatingFileHandler',
                'level': 'ERROR',
                'formatter': 'json',
                'filename': 'logs/error.log',
                'maxBytes': 10485760,  # 10MB
                'backupCount': 5,
                'encoding': 'utf8'
            },
            'file_agent': {
                'class': 'logging.handlers.RotatingFileHandler',
                'level': 'INFO',
                'formatter': 'json',
                'filename': 'logs/agent.log',
                'maxBytes': 10485760,  # 10MB
                'backupCount': 10,
                'encoding': 'utf8'
            }
        },
        'loggers': {
            '': {  # root logger
                'handlers': ['console', 'file_info', 'file_error'],
                'level': settings.log_level,
                'propagate': False
            },
            'app': {
                'handlers': ['console', 'file_info', 'file_error'],
                'level': settings.log_level,
                'propagate': False
            },
            'app.agents': {
                'handlers': ['console', 'file_agent'],
                'level': 'INFO',
                'propagate': False
            },
            'uvicorn': {
                'handlers': ['console', 'file_info'],
                'level': 'INFO',
                'propagate': False
            },
            'uvicorn.access': {
                'handlers': ['file_info'],
                'level': 'INFO',
                'propagate': False
            },
            'sqlalchemy.engine': {
                'handlers': ['file_info'],
                'level': 'WARNING' if not settings.debug else 'INFO',
                'propagate': False
            }
        }
    }
    
    # 应用日志配置
    logging.config.dictConfig(logging_config)
    
    # 配置 structlog
    structlog.configure(
        processors=[
            structlog.stdlib.filter_by_level,
            structlog.stdlib.add_logger_name,
            structlog.stdlib.add_log_level,
            structlog.stdlib.PositionalArgumentsFormatter(),
            structlog.processors.TimeStamper(fmt="iso"),
            structlog.processors.StackInfoRenderer(),
            structlog.processors.format_exc_info,
            structlog.processors.UnicodeDecoder(),
            structlog.processors.JSONRenderer()
        ],
        context_class=dict,
        logger_factory=structlog.stdlib.LoggerFactory(),
        wrapper_class=structlog.stdlib.BoundLogger,
        cache_logger_on_first_use=True,
    )


def get_logger(name: str = None) -> logging.Logger:
    """获取日志器"""
    return logging.getLogger(name or __name__)


def get_struct_logger(name: str = None):
    """获取结构化日志器"""
    return structlog.get_logger(name or __name__)


class LoggerMixin:
    """日志混入类"""
    
    @property
    def logger(self) -> logging.Logger:
        return get_logger(self.__class__.__name__)
    
    @property
    def struct_logger(self):
        return get_struct_logger(self.__class__.__name__)


class RequestLoggerMiddleware:
    """请求日志中间件"""
    
    def __init__(self, app):
        self.app = app
        self.logger = get_struct_logger("request")
    
    async def __call__(self, scope, receive, send):
        if scope["type"] != "http":
            await self.app(scope, receive, send)
            return
        
        start_time = datetime.utcnow()
        
        async def send_wrapper(message):
            if message["type"] == "http.response.start":
                end_time = datetime.utcnow()
                duration = (end_time - start_time).total_seconds()
                
                # 记录请求日志
                self.logger.info(
                    "HTTP请求完成",
                    method=scope["method"],
                    path=scope["path"],
                    query_string=scope.get("query_string", b"").decode(),
                    status_code=message["status"],
                    duration_seconds=duration,
                    client=scope.get("client"),
                    user_agent=dict(scope.get("headers", {})).get(b"user-agent", b"").decode(),
                )
            
            await send(message)
        
        await self.app(scope, receive, send_wrapper)


# 智能体专用日志器
agent_logger = get_struct_logger("agent")


def log_agent_action(agent_id: str, action: str, **kwargs):
    """记录智能体行为"""
    agent_logger.info(
        "智能体行为",
        agent_id=agent_id,
        action=action,
        **kwargs
    )


def log_agent_error(agent_id: str, error: str, **kwargs):
    """记录智能体错误"""
    agent_logger.error(
        "智能体错误",
        agent_id=agent_id,
        error=error,
        **kwargs
    )


def log_tool_usage(agent_id: str, tool_name: str, success: bool, duration: float, **kwargs):
    """记录工具使用"""
    agent_logger.info(
        "工具使用",
        agent_id=agent_id,
        tool_name=tool_name,
        success=success,
        duration_seconds=duration,
        **kwargs
    )


def log_conversation(agent_id: str, user_id: str, message_type: str, content: str, **kwargs):
    """记录对话"""
    agent_logger.info(
        "对话记录",
        agent_id=agent_id,
        user_id=user_id,
        message_type=message_type,
        content_length=len(content),
        **kwargs
    )


# 性能监控日志
performance_logger = get_struct_logger("performance")


def log_performance(operation: str, duration: float, **kwargs):
    """记录性能指标"""
    performance_logger.info(
        "性能指标",
        operation=operation,
        duration_seconds=duration,
        **kwargs
    )


# 安全日志
security_logger = get_struct_logger("security")


def log_security_event(event_type: str, user_id: str = None, ip_address: str = None, **kwargs):
    """记录安全事件"""
    security_logger.warning(
        "安全事件",
        event_type=event_type,
        user_id=user_id,
        ip_address=ip_address,
        **kwargs
    )


# 导出
__all__ = [
    "setup_logging",
    "get_logger",
    "get_struct_logger",
    "LoggerMixin",
    "RequestLoggerMiddleware",
    "agent_logger",
    "log_agent_action",
    "log_agent_error",
    "log_tool_usage",
    "log_conversation",
    "performance_logger",
    "log_performance",
    "security_logger",
    "log_security_event",
]